﻿#region Usings

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web.Mvc;
using Facebook.Rest;
using Facebook.Session;
using Omu.Awesome.Core;
using XPressify.Data.CompliedQueries;
using XPressify.Core;
using XPressify.Data;
using XPressify.Data.Helpers;
using XPressify.Models;

#endregion

namespace XPressify.Controllers
{
    public class HomeController : BaseController
    {
        public ActionResult Index()
        {
            ViewBag.LoggedIn = false;
            var session = new ConnectSession(ConfigurationManager.AppSettings["Facebook_API_Key"],
                                             ConfigurationManager.AppSettings["Facebook_API_Secret"]);
            ViewBag.Message = "Login with Facebook!";
            if (session.IsConnected())
            {
                try
                {
                    var facebook = new Api(session);

                    ViewBag.Message = "Hello, " + facebook.Users.GetInfo().name;
                    //var userImage = new Bitmap(facebook.Users.GetInfo().picture);
                    //var content = new System.IO.MemoryStream();
                    //userImage.Save(content, ImageFormat.Bmp);
                    //var webImage = new WebImage(content);
                    //var webImageResult = webImage.Write();

                    ViewBag.FacebookKey = ConfigurationManager.AppSettings["Facebook_API_Key"];
                }
                catch (Exception)
                {
                    // suppress the exception
                }
            }


            return View();
        }

        [Authorize]
        public ActionResult NewsFeed()
        {
            var rep = Repository;
            UserCompiledQueries.GetAllFriends(rep as Repository, Guid.Empty);
            var currentUser = CurrentUser;
            var allFriends = Repository.GetFriendsOf(currentUser.Id);
            var allPostTemp =
                Repository.AsQueryable<Post>().Where(
                    pst =>
                    (pst.PostType == PostType.Post || pst.PostType == PostType.PostNewsFeed) &&
                    (allFriends.Any(fr => fr.Id == pst.BaseSubject.Id) || pst.BaseSubject.Id == currentUser.Id)).
                    OrderByDescending(p => p.Created);

            //only news feed posts
            var newFeedPost = allPostTemp.Where(pst => pst.PostType == PostType.PostNewsFeed);
            var allPosts = allPostTemp.Where(pst => !newFeedPost.Any(nfp => nfp.Parent.Id == pst.Id));


            var allFriendsOfFriends =
                Repository.GetFriendsOfFriendsOf(currentUser.Id).Where(usr => usr.Id != currentUser.Id);
            var dictionary = new Dictionary<Post, List<Post>>();

            foreach (var post in allPosts)
            {
                var isOwnerOfPost = post.BaseSubject.Id == currentUser.Id;
                var areFriendsOfFriends = false;
                var areFriends = false;
                if(!isOwnerOfPost)
                {
                    areFriendsOfFriends = allFriendsOfFriends.Any(fr => fr.Id == post.BaseSubject.Id);
                    areFriends = allFriends.Any(fr => fr.Id == post.BaseSubject.Id);
                }
                if (isOwnerOfPost || (post.BaseObject.PrivacyType == ObjectPrivacy.Everyone ||
                    (post.BaseObject.PrivacyType == ObjectPrivacy.FriendsOnly && areFriends) ||
                    (post.BaseObject.PrivacyType == ObjectPrivacy.FriendsOfFriends && (areFriendsOfFriends || areFriends))))
                    {
                        if(post.PostType == PostType.PostNewsFeed)
                        {
                            var allComments = Repository.GetAllComments(post.Parent);
                            dictionary.Add(post, allComments);
                        }
                        else
                        {
                            var allComments = Repository.GetAllComments(post);
                            dictionary.Add(post, allComments);
                        }
                        
                    }
            }
            var wallAlbum =
                Repository.AsQueryable<Album>().SingleOrDefault(al => al.BaseSubject.Id == currentUser.Id && al.IsWall);
            var model = new NewsFeedModel()
                            {
                                AllPosts = dictionary,
                                ViewerUserId = currentUser.Id,
                                ViewerProfilePicturePath = Repository.GetProfilePicturePath(currentUser.Id),
                                WallAlbumId = wallAlbum.Id
                            };
            return View(model);
        }

        [Authorize]
        public ActionResult NotificationList(int? page)
        {
            var currentUser = CurrentUser;
            var notifications = Repository.AsQueryable<Notification>().Where(not => not.BaseSubject.Id == currentUser.Id);
            var listModel = new List<NotificationListModel>();
            var notificationPageable = notifications.GetPageable(page ?? 1, 10, (g => g.Created));
            foreach (var notification in notificationPageable.Page)
            {
                var newNotification = new NotificationListModel()
                                          {
                                              Notification = notification,
                                              DeleteSelected = false
                                          };
                listModel.Add(newNotification);
                if (notification.Active)
                {
                    notification.Active = false;
                }
            }
            Repository.SaveChanges();
            var notificationModelPageable = new Pageable<NotificationListModel>
                                                {
                                                    Page = listModel,
                                                    PageCount = notificationPageable.PageCount,
                                                    PageIndex = notificationPageable.PageIndex
                                                };
            return View(notificationModelPageable);
        }

        [Authorize]
        [HttpPost]
        public ActionResult DeleteNotification(Guid id)
        {
            var currentUser = CurrentUser;
            Notification notification = Repository.AsQueryable<Notification>().Where(not => not.Id == id).ToList().First();
            var myId = notification.Id;
            if(currentUser.Id != notification.BaseSubject.Id)
            {
                return RedirectToAction("NotificationList", "Home", new {});
            }
            notification.BaseSubject = null;
            Repository.DeleteObject(notification);
            Repository.SaveChanges();
            return PartialView("EmptyView");
//            return RedirectToAction("NotificationList", "Home", new { });
        }
        

        public ActionResult NewsFeedRefresh(string id)
        {
            var currentUser = CurrentUser;
            var guidId = new Guid(id);
            var lastPost = Repository.AsQueryable<Post>().SingleOrDefault(pst => pst.Id == guidId);

            var allFriends = Repository.GetFriendsOf(currentUser.Id);
            var allPostTemp =
                Repository.AsQueryable<Post>().Where(
                    pst =>
                    (pst.PostType == PostType.Post || pst.PostType == PostType.PostNewsFeed) &&
                    (allFriends.Any(fr => fr.Id == pst.BaseSubject.Id)) &&
                    DateTime.Compare(pst.Created, lastPost.Created) > 0).
                    OrderByDescending(p => p.Created);

            var allFriendsOfFriends =
                Repository.GetFriendsOfFriendsOf(currentUser.Id).Where(usr => usr.Id != currentUser.Id);
            var dictionary = new Dictionary<Post, List<Post>>();

            //only news feed posts
            var newFeedPost = allPostTemp.Where(pst => pst.PostType == PostType.PostNewsFeed);
            var allPosts = allPostTemp.Where(pst => !newFeedPost.Any(nfp => nfp.Parent.Id == pst.Id));

            //no new posts return empty view
            if(allPosts.Count() == 0)
            {
                return PartialView("EmptyView");
            }

            foreach (var post in allPosts)
            {
                var isOwnerOfPost = post.BaseSubject.Id == currentUser.Id;
                var areFriendsOfFriends = false;
                var areFriends = false;
                if (!isOwnerOfPost)
                {
                    areFriendsOfFriends = allFriendsOfFriends.Any(fr => fr.Id == post.BaseSubject.Id);
                    areFriends = allFriends.Any(fr => fr.Id == post.BaseSubject.Id);
                }
                if (isOwnerOfPost || (post.BaseObject.PrivacyType == ObjectPrivacy.Everyone ||
                    (post.BaseObject.PrivacyType == ObjectPrivacy.FriendsOnly && areFriends) ||
                    (post.BaseObject.PrivacyType == ObjectPrivacy.FriendsOfFriends && (areFriendsOfFriends || areFriends))))
                {
                    if (post.PostType == PostType.PostNewsFeed)
                    {
                        var allComments = Repository.GetAllComments(post.Parent);
                        dictionary.Add(post, allComments);
                    }
                    else
                    {
                        var allComments = Repository.GetAllComments(post);
                        dictionary.Add(post, allComments);
                    }

                }
            }
            var wallAlbum =
                Repository.AsQueryable<Album>().SingleOrDefault(al => al.BaseSubject.Id == currentUser.Id && al.IsWall);
            var model = new NewsFeedModel()
            {
                AllPosts = dictionary,
                ViewerUserId = currentUser.Id,
                ViewerProfilePicturePath = Repository.GetProfilePicturePath(currentUser.Id),
                WallAlbumId = wallAlbum.Id
            };
            return PartialView(model);

        }


        public ActionResult About()
        {
            return View();
        }

        public ActionResult Notify(NotifyModel model)
        {
            return View(model);
        }

        public ActionResult XdReceiver()
        {
            return View();
        }
    }
}